home *** CD-ROM | disk | FTP | other *** search
/ Celestin Apprentice 2 / Apprentice-Release2.iso / Source Code / C / Libraries / stdwin / Ports / x11 / event.c < prev    next >
Encoding:
C/C++ Source or Header  |  1991-05-28  |  5.3 KB  |  270 lines  |  [TEXT/????]

  1. /* X11 STDWIN -- High levent handling */
  2.  
  3. /* THIS CODE IS A MESS.  SHOULD BE RESTRUCTURED! */
  4.  
  5. #include "x11.h"
  6. #include "llevent.h"
  7. #include <X11/keysym.h>
  8.  
  9. static WINDOW *active;
  10. static WINDOW *prev_active;
  11.  
  12. /* Ensure none of the window pointers refer to the given window --
  13.    it's being closed so the pointer becomes invalid. */
  14.  
  15. _w_deactivate(win)
  16.     WINDOW *win;
  17. {
  18.     if (win == active)
  19.         active= NULL;
  20.     if (win == _w_new_active)
  21.         _w_new_active= NULL;
  22.     if (win == prev_active)
  23.         prev_active= NULL;
  24.     if (win == _w_bs.win) {
  25.         _w_bs.win= NULL;
  26.         _w_bs.down= FALSE;
  27.     }
  28. }
  29.  
  30. WINDOW *
  31. _w_get_last_active()
  32. {
  33.     if (_w_new_active != NULL)
  34.         return _w_new_active;
  35.     if (active != NULL)
  36.         return active;
  37.     if (prev_active != NULL)
  38.         return prev_active;
  39.     /* No window was ever active. Pick one at random. */
  40.     return _w_somewin();
  41. }
  42.  
  43. WINDOW *
  44. wgetactive()
  45. {
  46.     return active;
  47. }
  48.  
  49. /* wungetevent may be called from a signal handler.
  50.    If this is the case, we must send an event to ourselves
  51.    so it is picked up (eventually).
  52.    There is really still a race condition:
  53.    if wungetevent copies an event into the evsave buffer
  54.    when wgetevent is halfway of copying one out, we lose.
  55.    This can only be fixed with multiple buffers and I dont
  56.    want to think about that now. */
  57.  
  58. static bool in_getevent;
  59. EVENT _w_evsave;        /* Accessible by _w_ll_event */
  60.  
  61. void
  62. wungetevent(ep)
  63.     EVENT *ep;
  64. {
  65.     if (ep->type != WE_NULL) {
  66.         _w_evsave= *ep;
  67. #ifdef PIPEHACK
  68.         if (in_getevent) {
  69.             if (_wpipe[1] < 0)
  70.               _wwarning("wungetevent: can't interrupt wgetevent");
  71.             else if (write(_wpipe[1], "x", 1) != 1)
  72.               _wwarning("wungetevent: pipe write failed");
  73.             else
  74.               _wdebug(1, "wungetevent: wrote to pipe");
  75.         }
  76. #endif
  77.     }
  78. }
  79.  
  80. static void
  81. _wwaitevent(ep, mayblock)
  82.     EVENT *ep;
  83.     bool mayblock;
  84. {
  85.     XEvent e;
  86.     
  87.     in_getevent= TRUE;
  88.     
  89.     if (_w_evsave.type != WE_NULL) {
  90.         *ep= _w_evsave;
  91.         _w_evsave.type= WE_NULL;
  92.         in_getevent= FALSE;
  93.         return;
  94.     }
  95.     
  96.     /* Break out of this loop when we've got an event for the appl.,
  97.        or, if mayblock is false, when we would block (in XNextEvent) */
  98.     for (;;) {
  99.         if (_w_close_this != NULL) {
  100.             /* WM_DELETE_WINDOW detected */
  101.             ep->type = WE_CLOSE;
  102.             ep->window = _w_close_this;
  103.             _w_close_this = NULL;
  104.             break;
  105.         }
  106.         if (_w_lostselection(ep))
  107.             return;
  108.         if (_w_keysym != 0) {
  109.             if (_w_new_active != active) {
  110.                 if (active != NULL) {
  111.                     ep->type= WE_DEACTIVATE;
  112.                     ep->window= prev_active= active;
  113.                     active= NULL;
  114.                 }
  115.                 else {
  116.                     ep->type= WE_ACTIVATE;
  117.                     ep->window= active= _w_new_active;
  118.                 }
  119.             }
  120.             else {
  121.                 ep->type= WE_CHAR;
  122.                 ep->window= active;
  123.                 ep->u.character= _w_keysym;
  124.                 change_key_event(ep);
  125.                 _w_keysym= 0;
  126.             }
  127.             if (ep->type != WE_NULL)
  128.                 break;
  129.         }
  130.         if (_w_bs_changed || _w_moved) {
  131.             ep->type= WE_NULL;
  132.             switch (_w_bs.isub) {
  133.             case MBAR:
  134.                 _whitmbar(&_w_bs, ep);
  135.                 break;
  136.             case MWIN:
  137.                 _whitmwin(&_w_bs, ep); /* XXX test */
  138.                 break;
  139.             case HBAR:
  140.                 _whithbar(&_w_bs, ep);
  141.                 break;
  142.             case VBAR:
  143.                 _whitvbar(&_w_bs, ep);
  144.                 break;
  145.             case WA:
  146.                 ep->type= _w_moved ?
  147.                         WE_MOUSE_MOVE :
  148.                         _w_bs.down ?
  149.                             WE_MOUSE_DOWN :
  150.                             WE_MOUSE_UP;
  151.                 ep->window= _w_bs.win;
  152.                 ep->u.where.h= _w_bs.x;
  153.                 ep->u.where.v= _w_bs.y;
  154.                 ep->u.where.button= _w_bs.button;
  155.                 ep->u.where.clicks= _w_bs.clicks;
  156.                 ep->u.where.mask= _w_bs.mask;
  157.                 break;
  158.             }
  159.             _w_bs_changed= _w_moved= FALSE;
  160.             if (ep->type != WE_NULL)
  161.                 break;
  162.         }
  163.         if (_w_checktimer(ep, FALSE))
  164.             break;
  165.         if (XPending(_wd) == 0)
  166.             XSync(_wd, FALSE);
  167.         if (XPending(_wd) == 0) {
  168.             if (_w_new_active != active) {
  169.                 /* Why is this code duplicated here? */
  170.                 if (active != NULL) {
  171.                     ep->type= WE_DEACTIVATE;
  172.                     ep->window= prev_active= active;
  173.                     active= NULL;
  174.                 }
  175.                 else {
  176.                     ep->type= WE_ACTIVATE;
  177.                     ep->window= active= _w_new_active;
  178.                 }
  179.                 break;
  180.             }
  181.             if (_w_resized && _w_doresizes(ep))
  182.                 break;
  183.             if (_w_dirty && _w_doupdates(ep))
  184.                 break;
  185.             if (XPending(_wd) == 0 && _w_checktimer(ep, mayblock)
  186.                     || !mayblock)
  187.                 break;
  188.         }
  189. #ifdef PIPEHACK
  190.         if (_w_evsave.type != NULL) {
  191.             /* Lots of race conditions here! */
  192.             char dummy[256];
  193.             int n;
  194.             _wdebug(1, "wgetevent: got evt from handler");
  195.             *ep= _w_evsave;
  196.             _w_evsave.type= WE_NULL;
  197.             if ((n= read(_wpipe[0], dummy, sizeof dummy)) <= 0)
  198.               _wdebug(1, "wgetevent: read from pipe failed");
  199.             else if (n != 1)
  200.               _wdebug(0, "wgetevent: got %d bytes from pipe!", n);
  201.             break;
  202.         }
  203. #endif
  204.         XNextEvent(_wd, &e);
  205.         _w_ll_event(&e);
  206.     }
  207.     
  208.     in_getevent= FALSE;
  209. }
  210.  
  211. bool
  212. wpollevent(ep)
  213.     EVENT *ep;
  214. {
  215.     ep->type = WE_NULL;
  216.     _wwaitevent(ep, FALSE);
  217.     return ep->type != WE_NULL;
  218. }
  219.  
  220. void
  221. wgetevent(ep)
  222.     EVENT *ep;
  223. {
  224.     _wwaitevent(ep, TRUE);
  225. }
  226.  
  227. static
  228. change_key_event(ep)
  229.     EVENT *ep;
  230. {
  231.     if (_w_state & Mod1Mask) {
  232.         ep->type= WE_NULL;
  233.         _w_menukey(ep->u.character, ep);
  234.         return;
  235.     }
  236.     switch (ep->u.character) {
  237.     case XK_Left:
  238.         ep->u.command= WC_LEFT;
  239.         break;
  240.     case XK_Right:
  241.         ep->u.command= WC_RIGHT;
  242.         break;
  243.     case XK_Up:
  244.         ep->u.command= WC_UP;
  245.         break;
  246.     case XK_Down:
  247.         ep->u.command= WC_DOWN;
  248.         break;
  249.     case '\n':
  250.     case '\r':
  251.         ep->u.command= WC_RETURN;
  252.         break;
  253.     case '\3':
  254.         ep->u.command= WC_CANCEL;
  255.         break;
  256.     case '\b':
  257.     case '\177': /* DEL */
  258.         ep->u.command= WC_BACKSPACE;
  259.         break;
  260.     case '\t':
  261.         ep->u.command= WC_TAB;
  262.         break;
  263.     default:
  264.         if (ep->u.character < 0 || ep->u.character > 0177)
  265.             ep->type= WE_NULL;
  266.         return;
  267.     }
  268.     ep->type= WE_COMMAND;
  269. }
  270.